package com.demo.juc.unsafe;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName SimpleDateFormatUnsafe
 * @Author bsy
 * @Description
 * ThreadLocal  包装一层 ，解决：SimpleDateFormat线程非安全
 * 运行效率比较高，推荐在高并发业务场景的生产环境使用
 *
 * @Date 2022/10/1 11:04
 * @Version 1.0
 */
public class SimpleDateFormat4 {

    private static final int COUNT_DOWN_LATCH = 100000;  //执行总次数
    private static final int COUNT_SEMAPHORE = 20;       //同时运行的线程数量

    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    //相当于 用ThreadLocal 包装一层
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public static void main(String[] args) throws ParseException, InterruptedException {

        CountDownLatch countDownLatch = new CountDownLatch(COUNT_DOWN_LATCH);
        Semaphore semaphore = new Semaphore(COUNT_SEMAPHORE);

        ExecutorService threadPool = Executors.newCachedThreadPool();
        try {
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < COUNT_DOWN_LATCH; i++) {
                threadPool.execute(() -> {
                    try {
                        semaphore.acquire();
                        threadLocal.get().parse("2022-10-01");
                        //dateFormat.parse("2022-10-01");
                        semaphore.release();
                        countDownLatch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                });
            }

            long endTime = System.currentTimeMillis();
            System.out.println("执行总用时；" + (endTime - startTime) + "ms");

        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("日期处理异常：" + ex.getCause() + ex.getMessage());
        } finally {
            countDownLatch.await();
            threadPool.shutdown();
        }
    }
}
